﻿using System;
using System.Data.SQLite;

namespace CompactMapper.Orm.UnitOfWork
{
    public static class ConnectionFactory
    {
        private static ConnectionWrapper _inMemoryConnectionWrapper;

        public class ConnectionWrapper : IDisposable
        {
            private readonly SQLiteConnection _connection;
            private readonly Boolean _inMemory;

            public ConnectionWrapper(SQLiteConnection connection)
            {
                _connection = connection;
                _inMemory = InMemory(connection.ConnectionString);
            }

            public SQLiteConnection Connection
            {
                get { return _connection; }
            }

            public void Dispose()
            {
                if (_inMemory)
                    return;

                _connection.Dispose();
            }
        }


        internal static void Reset()
        {
            _inMemoryConnectionWrapper = null;
        }

        internal static ConnectionWrapper CreateConnection(String connectionString)
        {
            if (InMemory(connectionString))
            {
                return _inMemoryConnectionWrapper ??
                       (_inMemoryConnectionWrapper = new ConnectionWrapper(ActuallyCreateConnection(connectionString)));
            }
            return new ConnectionWrapper(ActuallyCreateConnection(connectionString));
        }

        private static Boolean InMemory(String connectionString)
        {
            return connectionString.Contains(":memory:");
        }


        private static SQLiteConnection ActuallyCreateConnection(String connectionString)
        {
            var connection = new SQLiteConnection(connectionString);
            connection.Open();
            var pragma = new SQLiteCommand("PRAGMA foreign_keys = true;", connection);
            pragma.ExecuteNonQuery();
            return connection;
        }
    }
}